home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / except.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  9.2 KB  |  346 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_CORE1_SEG
  14. #pragma code_seg(AFX_CORE1_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. void PASCAL CException::operator delete(void* pbData)
  19. {
  20.     // check for proper exception object deletion
  21.     CException* pException = (CException*)pbData;
  22.     // use: pException->Delete(), do not use: delete pException
  23.     ASSERT(pException->m_bReadyForDelete);
  24.     ASSERT(pException->m_bAutoDelete > 0);
  25.  
  26.     // avoid crash when assert above is ignored
  27.     if (pException->m_bReadyForDelete && pException->m_bAutoDelete > 0)
  28.         CObject::operator delete(pbData);
  29. }
  30.  
  31. #if _MSC_VER >= 1200
  32. void PASCAL CException::operator delete(void* pbData,
  33.     LPCSTR /* lpszFileName */, int /* nLine */)
  34. {
  35.     operator delete(pbData);
  36. }
  37. #endif
  38.  
  39. #undef THIS_FILE
  40. static char THIS_FILE[] = __FILE__;
  41. #define new DEBUG_NEW
  42. #endif
  43.  
  44. /////////////////////////////////////////////////////////////////////////////
  45. // AFX_EXCEPTION_CONTEXT (thread global state)
  46.  
  47. inline AFX_EXCEPTION_CONTEXT* AfxGetExceptionContext()
  48. {
  49.     DWORD lError = GetLastError();
  50.     AFX_EXCEPTION_CONTEXT* pContext = &_afxThreadState->m_exceptionContext;
  51.     SetLastError(lError);
  52.     return pContext;
  53. }
  54.  
  55. /////////////////////////////////////////////////////////////////////////////
  56. // CException
  57.  
  58. CException::CException()
  59. {
  60.     // most exceptions are deleted when not needed
  61.     m_bAutoDelete = TRUE;
  62. #ifdef _DEBUG
  63.     m_bReadyForDelete = FALSE;
  64. #endif
  65. }
  66.  
  67. CException::CException(BOOL bAutoDelete)
  68. {
  69.     // for exceptions which are not auto-delete (usually)
  70.     m_bAutoDelete = bAutoDelete;
  71. #ifdef _DEBUG
  72.     m_bReadyForDelete = FALSE;
  73. #endif
  74. }
  75.  
  76. void CException::Delete()
  77. {
  78.     // delete exception if it is auto-deleting
  79.     if (m_bAutoDelete > 0)
  80.     {
  81. #ifdef _DEBUG
  82.         m_bReadyForDelete = TRUE;
  83. #endif
  84.         delete this;
  85.     }
  86. }
  87.  
  88. BOOL CException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
  89.     PUINT pnHelpContext /* = NULL */ )
  90. {
  91.     if (pnHelpContext != NULL)
  92.         *pnHelpContext = 0;
  93.  
  94.     if (nMaxError != 0 && lpszError != NULL)
  95.         *lpszError = '\0';
  96.  
  97.     return FALSE;
  98. }
  99.  
  100. int CException::ReportError(UINT nType /* = MB_OK */,
  101.     UINT nError /* = 0 */)
  102. {
  103.     TCHAR   szErrorMessage[512];
  104.     int     nDisposition;
  105.     UINT    nHelpContext;
  106.  
  107.     if (GetErrorMessage(szErrorMessage, _countof(szErrorMessage), &nHelpContext))
  108.         nDisposition = AfxMessageBox(szErrorMessage, nType, nHelpContext);
  109.     else
  110.     {
  111.         if (nError == 0)
  112.             nError = AFX_IDP_NO_ERROR_AVAILABLE;
  113.         nDisposition = AfxMessageBox(nError, nType, nHelpContext);
  114.     }
  115.     return nDisposition;
  116. }
  117.  
  118. /////////////////////////////////////////////////////////////////////////////
  119. // AFX_EXCEPTION_LINK linked 'jmpbuf' and out-of-line helpers
  120.  
  121. AFX_EXCEPTION_LINK::AFX_EXCEPTION_LINK()
  122. {
  123.     // setup initial link state
  124. #ifdef _AFX_OLD_EXCEPTIONS
  125.     m_nType = 0;
  126. #endif
  127.     m_pException = NULL;    // no current exception yet
  128.  
  129.     // wire into top of exception link stack
  130.     AFX_EXCEPTION_CONTEXT* pContext = AfxGetExceptionContext();
  131.     m_pLinkPrev = pContext->m_pLinkTop;
  132.     pContext->m_pLinkTop = this;
  133. }
  134.  
  135. // out-of-line cleanup called from inline AFX_EXCEPTION_LINK destructor
  136. void AFXAPI AfxTryCleanup()
  137. {
  138.     AFX_EXCEPTION_CONTEXT* pContext = AfxGetExceptionContext();
  139.     AFX_EXCEPTION_LINK* pLinkTop = pContext->m_pLinkTop;
  140.  
  141.     // delete current exception
  142.     ASSERT(pLinkTop != NULL);
  143.     if (pLinkTop->m_pException != NULL)
  144.         pLinkTop->m_pException->Delete();
  145.  
  146.     // remove ourself from the top of the chain
  147.     pContext->m_pLinkTop = pLinkTop->m_pLinkPrev;
  148. }
  149.  
  150. #ifndef _AFX_OLD_EXCEPTIONS
  151. // special out-of-line implementation of THROW_LAST (for auto-delete behavior)
  152. void AFXAPI AfxThrowLastCleanup()
  153. {
  154.     AFX_EXCEPTION_CONTEXT* pContext = AfxGetExceptionContext();
  155.     AFX_EXCEPTION_LINK* pLinkTop = pContext->m_pLinkTop;
  156.  
  157.     // check for THROW_LAST inside of auto-delete block
  158.     if (pLinkTop != NULL)
  159.     {
  160.         // make sure current exception does not get auto-deleted
  161.         pLinkTop->m_pException = NULL;
  162.     }
  163.  
  164.     // THROW_LAST macro will do actual 'throw'
  165. }
  166. #endif //!_AFX_OLD_EXCEPTIONS
  167.  
  168. /////////////////////////////////////////////////////////////////////////////
  169. // Global exception terminate handling - Obsolete API
  170. //  (apps written to C++ exceptions should use set_terminate)
  171.  
  172. #ifdef _AFX_OLD_EXCEPTIONS
  173.  
  174. void AFXAPI AfxTerminate()
  175. {
  176.     TRACE0("AfxTerminate called.\n");
  177.     (*AfxGetModuleState()->m_pfnTerminate)();
  178. }
  179.  
  180. AFX_TERM_PROC AFXAPI AfxSetTerminate(AFX_TERM_PROC pfnNew)
  181. {
  182.     AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  183.     AFX_TERM_PROC pfnOld = pModuleState->m_pfnTerminate;
  184.     pModuleState->m_pfnTerminate = pfnNew;
  185.     return pfnOld;
  186. }
  187.  
  188. #endif //_AFX_OLD_EXCEPTIONS
  189.  
  190. /////////////////////////////////////////////////////////////////////////////
  191. // Special non-C++ exception implementation
  192.  
  193. #ifdef _AFX_OLD_EXCEPTIONS
  194. // out-of-line implementation of THROW (for non-C++ exceptions)
  195. void AFXAPI AfxThrow(CException* pNewException)
  196. {
  197. #if defined(_WIN32_WCE)
  198. // WinCE: if an exception gets fired we might be in the middle of a CWaitCursor constructor/destructor pair, 
  199. // so let's halt the hour glass (which gets in the way of any error dialog box).
  200.     CWinApp *pApp = AfxGetApp();
  201.     if(pApp != NULL)
  202.         pApp->DoWaitCursor(INT_MIN);
  203. #endif // _WIN32_WCE
  204.  
  205.     // get current exception context for running task
  206.     AFX_EXCEPTION_CONTEXT* pContext = AfxGetExceptionContext();
  207.  
  208.     // check for THROW_LAST() first
  209.     if (pNewException == NULL)
  210.     {
  211.         ASSERT(pContext->m_pLinkTop != NULL);
  212.         pNewException = pContext->m_pLinkTop->m_pException;
  213.     }
  214.     ASSERT_VALID(pNewException);
  215.  
  216.     TRACE1("Warning: Throwing an Exception of type %hs.\n",
  217.         pNewException->GetRuntimeClass()->m_lpszClassName);
  218.  
  219.     while (pContext->m_pLinkTop != NULL)
  220.     {
  221.         AFX_EXCEPTION_LINK* pReceiver = pContext->m_pLinkTop;
  222.         if (pReceiver->m_pException != NULL)
  223.         {
  224.             // a THROW during a CATCH block -- this link may not be
  225.             //  destructed, so it is necessary to do all the cleanup that
  226.             //  the destructor would do.
  227.             if (pReceiver->m_pException != pNewException)
  228.                 pReceiver->m_pException->Delete();
  229.             pReceiver->m_pException = NULL;
  230.             pContext->m_pLinkTop = pReceiver->m_pLinkPrev;
  231.         }
  232.         else
  233.         {
  234.             // throw the exception to the top handler (if appropriate type)
  235.             if (pReceiver->m_nType == 0)
  236.             {
  237.                 // setup the receiver's context for the new exception
  238.                 pReceiver->m_pException = pNewException;
  239.  
  240.                 // and jump into the handler...
  241.                 longjmp(pReceiver->m_jumpBuf, 1);
  242.                 ASSERT(FALSE);  // not reached
  243.             }
  244.             // otherwise just call cleanup proc
  245.             (*pReceiver->m_callback.pfnCleanup)(pReceiver);
  246.         }
  247.     }
  248.  
  249.     ASSERT(pContext->m_pLinkTop == NULL);
  250.     // uncaught exception, terminate
  251.     TRACE1("Error: Uncaught Exception (%hs).\n",
  252.         pNewException->GetRuntimeClass()->m_lpszClassName);
  253.     AfxTerminate();
  254.     ASSERT(FALSE);  // not reached
  255. }
  256.  
  257. // out-of-line implementation of CATCH and AND_CATCH
  258. BOOL AFXAPI AfxCatchProc(CRuntimeClass* pClass)
  259. {
  260.     ASSERT(pClass != NULL);
  261.  
  262.     AFX_EXCEPTION_CONTEXT* pContext = AfxGetExceptionContext();
  263.     ASSERT(pContext->m_pLinkTop != NULL);
  264.     CException* pException = pContext->m_pLinkTop->m_pException;
  265.     ASSERT(pException != NULL);
  266.  
  267.     return pException->IsKindOf(pClass);
  268. }
  269. #endif //_AFX_OLD_EXCEPTIONS
  270.  
  271. #ifdef AFX_INIT_SEG
  272. #pragma code_seg(AFX_INIT_SEG)
  273. #endif
  274.  
  275. IMPLEMENT_DYNAMIC(CException, CObject)
  276.  
  277. IMPLEMENT_DYNAMIC(CMemoryException, CException)
  278. CMemoryException _simpleMemoryException(FALSE, AFX_IDS_MEMORY_EXCEPTION);
  279.  
  280. IMPLEMENT_DYNAMIC(CNotSupportedException, CException)
  281. CNotSupportedException _simpleNotSupportedException(FALSE, AFX_IDS_NOT_SUPPORTED_EXCEPTION);
  282.  
  283. /////////////////////////////////////////////////////////////////////////////
  284. // Standard exceptions
  285.  
  286. #ifdef AFX_AUX_SEG
  287. #pragma code_seg(AFX_AUX_SEG)
  288. #endif
  289.  
  290. void CSimpleException::InitString()
  291. {
  292.     m_bInitialized = TRUE;
  293.     m_bLoaded = (AfxLoadString(m_nResourceID,
  294.         m_szMessage, _countof(m_szMessage)) != 0);
  295. }
  296.  
  297. BOOL CSimpleException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
  298.         PUINT pnHelpContext)
  299. {
  300.     ASSERT(lpszError != NULL && AfxIsValidString(lpszError, nMaxError));
  301.  
  302.     if (pnHelpContext != NULL)
  303.         *pnHelpContext = 0;
  304.  
  305.     // if we didn't load our string (eg, we're a console app)
  306.     // return a null string and FALSE
  307.  
  308.     if (!m_bInitialized)
  309.         InitString();
  310.  
  311.     if (m_bLoaded)
  312.         lstrcpyn(lpszError, m_szMessage, nMaxError);
  313.     else
  314.         lpszError[0] = '\0';
  315.  
  316.     return m_bLoaded;
  317. }
  318.  
  319. void AFXAPI AfxThrowMemoryException()
  320. {
  321.     THROW(&_simpleMemoryException);
  322. }
  323.  
  324. void AFXAPI AfxThrowNotSupportedException()
  325. {
  326.     THROW(&_simpleNotSupportedException);
  327. }
  328.  
  329. #ifdef AFX_INIT_SEG
  330. #pragma code_seg(AFX_INIT_SEG)
  331. #endif
  332.  
  333. ////////////////////////////////////////////////////////////////////////////
  334. // out-of-line inlines for binary compatibility
  335.  
  336. #ifdef _AFXDLL
  337. #ifndef _DEBUG
  338.  
  339. CSimpleException::~CSimpleException()
  340.     { }
  341.  
  342. #endif
  343. #endif
  344.  
  345. /////////////////////////////////////////////////////////////////////////////
  346.